package ua.edu.nuos.jeetraining2012.cms.util.mail;

import freemarker.template.Configuration;
import org.slf4j.Logger;
import ua.edu.nuos.jeetraining2012.cms.entity.CourseEntity;
import ua.edu.nuos.jeetraining2012.cms.entity.UserEntity;
import ua.edu.nuos.jeetraining2012.cms.service.Course;

import javax.mail.internet.InternetAddress;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.validation.ValidatorFactory;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

/**
 * @author Victor N. Ganichev victor.ganichev@gmail.com
 * @version 1.0 Date: 01.07.13 Time: 20:07
 * @since 1.0
 */
abstract public class NotifyInstructor implements Sendable {

    /** Define validator. */
    protected ValidatorFactory validatorFactory;

    /** Define ResourceBundle. */
    protected ResourceBundle i18n;

    /** Define course entity. */
    protected CourseEntity course;

    /** Define instructor entity. */
    protected List<UserEntity> instructorList;

    /** Define student entity. */
    protected UserEntity student;

    /** Define service layer for course. */
    protected Course courseService;


    /** Define logger. */
    final private static Logger logger = org.slf4j.LoggerFactory.getLogger(NotifyInstructor.class);

    // Constructors
    public NotifyInstructor() {
        super();
        try {
            InitialContext ic = new InitialContext();

            validatorFactory = (ValidatorFactory) ic.lookup("java:comp/ValidatorFactory");
            logger.debug("ValidationFactory component injected.");

            courseService = (Course) ic.lookup("java:module/Course");
            logger.debug("Injecting course EJB");

        } catch (NamingException e) {
            logger.error("Can't init InitialContext.");
        }
    }

    // Getters & Setters
    public CourseEntity getCourse() {
        return course;
    }

    public void setCourse(CourseEntity course) {
        this.course = course;
    }

    public List<UserEntity> getInstructorList() {
        return instructorList;
    }

    public void setInstructorList(List<UserEntity> instructorList) {
        this.instructorList = instructorList;
    }

    public UserEntity getStudent() {
        return student;
    }

    public void setStudent(UserEntity student) {
        this.student = student;
    }

    /** @inheritDoc */
    @Override
    public List<InternetAddress> getRecipientList() {
        logger.debug("getRecipientList() - started.");
        List<InternetAddress> rcpt = new ArrayList<>();

        try {
            for (UserEntity instructor : instructorList) {
                logger.debug("Creating inet address for email {} & name {}", instructor.getEmail(), instructor.getName());
                rcpt.add(doInetAddr(instructor.getEmail(), instructor.getName()));
            }
        } catch (UnsupportedEncodingException e) {
            logger.debug("Can't create InternetAddress");
        }
        logger.debug("{} addresses created", rcpt.size());

        logger.debug("getRecipientList() - finished.");
        return rcpt;
    }

    @Override
    public List<InternetAddress> getCCList() {
        return new ArrayList<>();
    }

    @Override
    public List<InternetAddress> getBCCList() {
        return new ArrayList<>();
    }

    protected Configuration getTemplateConfig() {
        Configuration cfg = new Configuration();
        cfg.setClassForTemplateLoading(getClass(), "/templates/mail");
        return cfg;
    }

    /**
     * Return formed email address.
     *
     * @param instructorEmail                   Instructors email
     * @param instructorName                    Instructors name
     * @return                                  Formed email ready to be used in rcpt list.
     * @throws UnsupportedEncodingException     If charset is not supported.
     */
    private InternetAddress doInetAddr(String instructorEmail, String instructorName) throws UnsupportedEncodingException {
        return new InternetAddress(instructorEmail, instructorName, "UTF-8");
    }
}
